/**
 * Copyright (C) 2021 - 2031 O-Cubes Co., Ltd.
 */

/****************************************************************
 *  @file    error.h
 *  @brief   Error definition header file
 *  @version v1.0
 *  @date    03. Apr. 2023
 *  @author  gonght
 ****************************************************************/
#ifndef __ERROR_H__
#define __ERROR_H__

#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif
/**
 * @name  Main Error Code Definitions
 * @{
 */
#define E_OK            (0)             /*!< ok */
#define E_FAILURE       (-1)            /*!< failure */
#define E_SYS           (-5)            /*!< system error */
#define E_NOSPT         (-9)            /*!< unsupported features */
#define E_RSFN          (-10)           /*!< reserved function code */
#define E_RSATR         (-11)           /*!< reserved attribute */
#define E_PAR           (-17)           /*!< parameter error */
#define E_ID            (-18)           /*!< invalid ID number */
#define E_CTX           (-25)           /*!< context error */
#define E_MACV          (-26)           /*!< memory access violation */
#define E_OACV          (-27)           /*!< object access violation */
#define E_ILUSE         (-28)           /*!< illegal service call use */
#define E_NOMEM         (-33)           /*!< insufficient memory */
#define E_NOID          (-34)           /*!< no ID number available */
#define E_NORES         (-35)           /*!< no resource available */
#define E_OBJ           (-41)           /*!< object state error */
#define E_NOEXS         (-42)           /*!< non-existent object */
#define E_QOVR          (-43)           /*!< queue overflow */
#define E_RLWAI         (-49)           /*!< forced release from waiting */
#define E_TMOUT         (-50)           /*!< polling failure or timeout */
#define E_DLT           (-51)           /*!< waiting object deleted */
#define E_CLS           (-52)           /*!< waiting object state changed */
#define E_WBLK          (-57)           /*!< non-blocking accepted */
#define E_BOVR          (-58)           /*!< buffer overflow */
#define E_OPNED         (-6)            /*!< device is opened */
#define E_CLSED         (-7)            /*!< device is closed */

/**
 * @brief compiler_rarely(expr) evaluates expression expr and
 *        informs the compiler that the value is rarely true.
 */
#define compiler_rarely(a)          __builtin_expect(!!(a), 0)

/**
 * @name  Check Error
 * @{
 */
/**
 * @brief   check an expression to see if it is right, and when error
 *          set the ercd, and goto exit_label
 * @param   EXPR	the expression that need to be checked (==0 failed)
 * @param   ERCD	MUST pass a variable to here to get the error code
 * @param   ERROR_CODE error code that pass to ERCD
 * @param   EXIT_LABEL a label to go when error happens
 */
#define CHECK_EXP(EXPR, ERCD, ERROR_CODE, EXIT_LABEL)   { \
		if (compiler_rarely(!(EXPR))) {           \
			ERCD = (ERROR_CODE);              \
			goto EXIT_LABEL;                  \
		}                                         \
	}
/**
 * @brief   check an expression to see if it is right, and when error
 *			directly goto exit_label
 * @param   EXPR       the expression that need to be checked (==0 failed)
 * @param   EXIT_LABEL a label to go when error happens
 */
#define CHECK_EXP_NOERCD(EXPR, EXIT_LABEL) {             \
		if (compiler_rarely(!(EXPR))) {          \
			goto EXIT_LABEL;                 \
		}                                        \
	}
/** check cnt bytes align, 1 for aligned, 0 for not-aligned */
#define CHECK_ALIGN_BYTES(pointer, cnt)         (((uint32_t)(pointer) & (uint32_t)(cnt - 1)) == 0)
/** check 2 bytes align, 1 for aligned, 0 for not-aligned */
#define CHECK_ALIGN_2BYTES(pointer)             (((uint32_t)(pointer) & (uint32_t)0x1) == 0)
/** check 4 bytes align, 1 for aligned, 0 for not-aligned */
#define CHECK_ALIGN_4BYTES(pointer)             (((uint32_t)(pointer) & (uint32_t)0x3) == 0)
/** check 8 bytes align, 1 for aligned, 0 for not-aligned */
#define CHECK_ALIGN_8BYTES(pointer)             (((uint32_t)(pointer) & (uint32_t)0x7) == 0)
/** @} end of name */

#ifdef __cplusplus
}
#endif

#endif  /* __ERROR_H__ */

